package com.vivachek.protocol

import java.util.*

/**
 * @Author: YCB
 * @Time: 2022/10/8 16:20:11
 * @Email: congbin.yuan@vivachek.com
 * @Description: 扩展类,主要解析蓝牙广播包中的设备SN号
 */

/**
 * 如需过滤其他设备,请将此uuid加入到蓝牙扫描的配置中
 */
//val SCAN_DEVICE_UUID = mutableListOf(
//    UUID.fromString("00006958-0000-1000-8000-00805f9b34fb"),
//    UUID.fromString("0000fee7-0000-1000-8000-00805f9b34fb"),
//)

/**
 * 设备主服务的uuid
 */
val DEVICE_PRIMARY_UUID = UUID.fromString("0003cdd0-0000-1000-8000-00805f9b0131")

/**
 * 设备写服务的uuid
 */
val DEVICE_WRITE_UUID = UUID.fromString("0003cdd2-0000-1000-8000-00805f9b0131")

/**
 * 接收设备数据的UUID
 */
val DEVICE_RECEIVER_UUID = UUID.fromString("0003cdd1-0000-1000-8000-00805f9b0131")

/**
 * 从广播包中解析设备的sn号
 */
fun parseSnFromScanRecord(scanRecord: ByteArray?): String {
    scanRecord ?: return ""
    val byteArray = scanRecord.toMutableList()
    var index = 0
    var deviceMAC: List<Byte>? = null
    var deviceSN = ""
    var deviceName = ""
    while (index < byteArray.size) {
        val byte = byteArray[index]
        val realLen = byte.toInt()
        val realData = byteArray.subList(index, index + realLen + 1)
        index += realLen + 1
        if (realLen == 9 && realData[1] == 0xFF.toByte()) {
            deviceMAC = parseMACFromScanRecord(realData.subList(4, realData.size))
            var mac = ""
            deviceMAC.map {
                mac += String.format("%02X:", it.toInt().and(255))
            }
            mac = mac.removeSuffix(":")
        }
        if (realLen == 9 && realData[1] == 0x16.toByte()) {
            deviceSN = parseSNFromScanRecord(deviceMAC, realData.subList(2, realData.size))
        }
        if (realLen == 13 && realData[1].toInt() == 9) {
            deviceName = parseDeviceName(realData.subList(2, realData.size))
        }
    }
    return deviceSN
}

private fun parseDeviceName(data: MutableList<Byte>): String {
    val sb = StringBuilder()
    data.forEach {
        sb.append(it.toInt().toChar())
    }
    return sb.toString()
}

private val secretKey = charArrayOf('H', 'z', 'W', 'c', 'B', 't', 'C')
private val notReadSN = mutableListOf<Byte>(0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00)
private fun parseSNFromScanRecord(mac: List<Byte>?, data: MutableList<Byte>): String {
    if (mac.isNullOrEmpty()) return ""
    if (data.isEmpty()) return ""
    if (mac.size != 6) return ""
    if (notReadSN == data) return ""
    val sn = StringBuilder()
    mac.forEachIndexed { index, byte ->
        val snUnEncrypt = data[index].toInt().and(255) xor (secretKey[index].toInt())
        val snInt = byte.toInt().and(255) xor snUnEncrypt
        sn.append(String.format("%02X", snInt))
    }
    val snUnEncrypt = data[data.lastIndex - 1].toInt().and(255) xor (secretKey[data.lastIndex - 1].toInt())
    val snInt = mac[0].toInt().and(255) xor snUnEncrypt
    sn.append(snInt.toString(16))
    var ret = sn.toString()
    if (ret.length >= 13) {
        ret = ret.substring(2)
    }
    return ret.toUpperCase(Locale.ROOT)
}

private fun parseMACFromScanRecord(data: MutableList<Byte>): List<Byte> {
    val mac = mutableListOf<Byte>()
    if (data.isEmpty()) {
        return mutableListOf()
    }
//    data.forEach {
//        mac.add(String.format("%02X", it.toInt().and(255)))
//    }
//    return mac
    return data
}